// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.core.resource;

import java.util.ArrayList;
import java.util.List;

import org.dengues.model.DenguesModelManager;
import org.dengues.model.project.ConnPropertyAttriType;
import org.dengues.model.project.ConnPropertySetType;
import org.dengues.model.project.ProjectPackage;
import org.dengues.model.project.ProjectType;
import org.dengues.model.project.UserType;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $
 * 
 */
public class DenguesProjectFactory {

    private static ResourceSet resourceSet = new ResourceSetImpl();

    private static String DENGUES_PROJECT = "dengues.project"; //$NON-NLS-1$

    private static final String RESOURCE = "resource"; //$NON-NLS-1$

    private static final String PLATFORM = "platform"; //$NON-NLS-1$

    private static final String TEMP_DIRECTORY = "temp"; //$NON-NLS-1$

    /**
     * Qiang.Zhang.Adolf@gmail.com DenguesProjectFactory constructor comment.
     */
    public DenguesProjectFactory() {
    }

    private static List<DenguesProject> denguesPrjs;

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "readProjects".
     * 
     * @return
     */
    public static DenguesProject[] readProjects() {
        IProject[] projects = getProjetWithNature(DenguesProjectNature.ID);
        denguesPrjs = new ArrayList<DenguesProject>();
        for (IProject project : projects) {
            if (hasDenguesProject(project)) {
                URI uri = URI.createPlatformResourceURI(project.getFullPath().append(DENGUES_PROJECT).toString());
                Resource resource = resourceSet.getResource(uri, true);
                ProjectType connection = (ProjectType) EcoreUtil.getObjectByType(resource.getContents(), ProjectPackage.eINSTANCE
                        .getProjectType());
                if (connection.getName() == null) {
                    connection.setName(project.getName());
                }
                if (connection.getComment() == null) {
                    connection.setComment(""); //$NON-NLS-1$
                }
                DenguesProject denguesProject = new DenguesProject(connection);
                denguesProject.setProject(project);
                denguesPrjs.add(denguesProject);
            }
        }
        return denguesPrjs.toArray(new DenguesProject[denguesPrjs.size()]);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createProject".
     * 
     * @param label
     * @param comment
     * @param userEmail
     * @param userName
     * @return
     */
    public static DenguesProject createProject(String label, String comment, String userEmail, String userName) {
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IProject prj = root.getProject(label);
        DenguesProject denguesProject = new DenguesProject();
        try {
            DenguesResourceManager.initDenguesProject(prj, comment);
            Resource resource = createProjectResource(prj);
            ProjectType projectType = denguesProject.getProjectType();
            projectType.setName(label);
            projectType.setComment(comment);
            UserType user = DenguesModelManager.getProjectFactory().createUserType();
            user.setEMail(userEmail);
            user.setName(userName);
            projectType.setUser(user);
            addDefaultHSQLDB(projectType, label);
            resource.getContents().add(projectType);
            prj.open(IResource.BACKGROUND_REFRESH, null);
            resource.save(null);
            denguesProject.setProject(prj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return denguesProject;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "addDefaultHSQLDB".
     * 
     * @param projectType
     * @param label
     */
    private static void addDefaultHSQLDB(ProjectType projectType, String label) {
        ConnPropertySetType connPropertySetType = DenguesModelManager.getProjectFactory().createConnPropertySetType();
        connPropertySetType.setId("DriverDefn.DATABASE.HypersonicSQL.Hsqldb Server");
        connPropertySetType.setName("Hsqldb Server");
        connPropertySetType
                .setKeys("jarList org.dengues.connectivity.port org.dengues.connectivity.driver org.dengues.connectivity.username org.dengues.connectivity.sid org.dengues.connectivity.host org.dengues.connectivity.password org.dengues.connectivity.url ");
        ConnPropertyAttriType connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("jarList");
        connAttriType.setValue("org.dengues.libraries/hsqldb.jar");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.driver");
        connAttriType.setValue("org.hsqldb.jdbcDriver");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.port");
        connAttriType.setValue("9001");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.username");
        connAttriType.setValue("sa");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.sid");
        connAttriType.setValue(label.toLowerCase());
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.host");
        connAttriType.setValue("localhost");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.url");
        connAttriType.setValue("jdbc:hsqldb:hsql://localhost:9001/");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);

        connAttriType = DenguesModelManager.getProjectFactory().createConnPropertyAttriType();
        connAttriType.setName("org.dengues.connectivity.password");
        connAttriType.setValue("");
        connAttriType.setPropertySet(connPropertySetType);
        connPropertySetType.getAttributes().add(connAttriType);
        projectType.getConnProperties().add(connPropertySetType);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createProjectResource".
     * 
     * @param project
     * @return
     */
    public static Resource createProjectResource(IProject project) {
        URI uri = URI.createPlatformResourceURI(project.getFullPath().append(DENGUES_PROJECT).toString());
        return resourceSet.createResource(uri);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getProjetWithNature".
     * 
     * @param natureId
     * @return
     */
    public static IProject[] getProjetWithNature(String natureId) {
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IProject[] projects = root.getProjects();
        List<IProject> projs = new ArrayList<IProject>();
        for (IProject project : projects) {
            try {
                if (project.hasNature(natureId)) {
                    projs.add(project);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        IProject[] prjs = new IProject[projs.size()];
        prjs = projs.toArray(prjs);
        return prjs;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "hasDenguesProject".
     * 
     * @param project
     * @return
     */
    public static boolean hasDenguesProject(IProject project) {
        URI uri = URI.createPlatformResourceURI(project.getFullPath().append(DENGUES_PROJECT).toString());
        IPath path = convert(uri);
        IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
        return file.exists();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "convert".
     * 
     * @param uri
     * @return
     */
    public static IPath convert(URI uri) {
        if (PLATFORM.equals(uri.scheme()) && uri.segmentCount() > 1 && RESOURCE.equals(uri.segment(0))) {
            StringBuffer platformResourcePath = new StringBuffer();
            for (int i = 1, size = uri.segmentCount(); i < size; ++i) {
                platformResourcePath.append('/');
                platformResourcePath.append(URI.decode(uri.segment(i)));
            }
            return new Path(platformResourcePath.toString());
        }

        return null;
    }

    private static DenguesProject denguesProject;

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getDenguesProject".
     * 
     * @param prjName
     * @return
     */
    public static DenguesProject getDenguesProject(String prjName) {
        for (DenguesProject dprj : denguesPrjs) {
            if (dprj.getName().equals(prjName)) {
                denguesProject = dprj;
                return dprj;
            }
        }
        return null;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getDenguesProject".
     * 
     * @return
     */
    public static DenguesProject getDenguesProject() {
        return denguesProject;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getTempFolder".
     * 
     * @return
     */
    public static IFolder getTempFolder() {
        try {
            IFolder folder = getDenguesProject().getProject().getFolder(TEMP_DIRECTORY);
            if (!folder.exists()) {
                folder.create(true, true, null);
            }
            return folder;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
